package vg.modules.notepad.components.textComponent;

import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;
import javax.swing.text.*;

import vg.services.main_manager.MainManager;

/**
 *  This class will display line numbers for a related text component. The text
 *  component must use the same line height for each line. TextLineNumber
 *  supports wrapped lines and will highlight the line number of the current
 *  line in the text component.
 *
 *  This class was designed to be used as a component added to the row header
 *  of a JScrollPane.
 */
public class TextLineNumber {
	// Components
	private final JTextPane textPane;
	private final JPanel view;
	// Mutex
	private final Object theMutexObjext;
	// Defines
	private final static Color DEF_BACKGROUND_COLOR = new Color(255,255,255);
	private final static Color DEF_BORDER_COLOR = new Color(108,226,108);
	/**
	 * Constructor.
	 */
	public TextLineNumber(JTextComponent component) {
		// init mutex
		this.theMutexObjext = new Object();
		// init components
		this.view = new JPanel(new GridBagLayout());
		this.textPane = new JTextPane();
		this.textPane.setEditable(false);
		this.textPane.setBackground(DEF_BACKGROUND_COLOR);
		// set color
		this.view.setBackground(DEF_BACKGROUND_COLOR);
		this.view.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 3, DEF_BORDER_COLOR));
		Font oldFont = component.getFont();
		Font newFont = new Font(oldFont.getFamily(), 0, oldFont.getSize());
		this.textPane.setFont(newFont);
		// pack ui
		GridBagConstraints gbc = new GridBagConstraints(0,0, 1,1, 1,1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 2, 0, 2), 0,0);
		this.view.add(this.textPane, gbc);
		// add listeners
		component.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				synchronized (theMutexObjext) {					
					if(evt != null) {
						String name = evt.getPropertyName();
						if(name != null && name.equals("font")) {
							Font oldFont = (Font)evt.getNewValue();
							Font newFont = new Font(oldFont.getFamily(), 0, oldFont.getSize());
							TextLineNumber.this.textPane.setFont(newFont);
						}
					}
				}
			}
		});
	}
	/**
	 * This method sets line count.
	 */
	public void setLineCount(final int count) {
		synchronized (this.theMutexObjext) {
			StringBuffer buffer = new StringBuffer();
			for(int i = 0; i < count; i++) {
				buffer.append(i);
				if(i < count-1) {
					buffer.append("\n");
				}
			}
			// set alignment
			Font font = this.textPane.getFont();
			StyleContext context = new StyleContext();
			StyledDocument document = new DefaultStyledDocument(context);

		    Style style = context.getStyle(StyleContext.DEFAULT_STYLE);
		    StyleConstants.setAlignment(style, StyleConstants.ALIGN_RIGHT);
		    StyleConstants.setFontSize(style, font.getSize());
		    try {
		    	document.insertString(0, buffer.toString(), style);
		    	this.textPane.setDocument(document);
		    } catch (BadLocationException ex) {
		    	MainManager.logger.printException(ex);
		    }
		}
	}
	public JComponent getView() {
		return(this.view);
	}
}
